package com.cal.utms.model.dealing;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import com.cal.utms.dao.dealing.DealDao;
import com.cal.utms.dto.dealing.ShortMaturityDto;
import com.cal.utms.entity.Deal;
import com.cal.utms.entity.DealInstrumentMap;
import com.cal.utms.entity.InstrumentTransaction;

public class ShortMaturityModel {

	public Deal doShortMature(ShortMaturityDto shortMaturityDto) {
		Deal newDeal = null;
		Deal oldDeal = null;
		String dealCode = null;
		DealDao dealDao = new DealDao();
		DateFormat df = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
		Date newMatDate = null;
		oldDeal = dealDao.getById(shortMaturityDto.getDealId());
		if (oldDeal == null) {
			shortMaturityDto.setStatus("Cannot find Deal");
			shortMaturityDto.setSuccess(false);
			return newDeal;
		}
		try {
			newMatDate = df.parse(shortMaturityDto.getNewMaturityDate());
		} catch (ParseException pe) {
			System.out.println("Error in Parse ShortMaturity new Date: " + shortMaturityDto.getNewMaturityDate());
			shortMaturityDto.setStatus("New Maturity Date Parse Error");
			shortMaturityDto.setSuccess(false);
			return newDeal;
		}

		newDeal = Deal.createClone(oldDeal);

		dealCode = "S" + oldDeal.getDealCode();
		newDeal.setDealCode(dealCode);
		newDeal.setStatus("Confirmed");
		newDeal.setMaturityDate(newMatDate);
		newDeal.setDeal(oldDeal);
		newDeal.setRolloverShortmaturity("ShortMatured from " + oldDeal.getDealCode() + ";");
		newDeal.setStatusChangeDate(new Date());
		newDeal.setModifiedDate(new Date());
		newDeal.setModifiedUser(shortMaturityDto.getUser());
		if (oldDeal.getName() != null) {
			newDeal.setName(oldDeal.getName() + " Temp");
		}

		oldDeal.setStatus("ShortMatured");
		oldDeal.setRolloverShortmaturity(newDeal.getDealCode());
		oldDeal.setStatusChangeDate(new Date());
		oldDeal.setModifiedDate(new Date());
		oldDeal.setModifiedUser(shortMaturityDto.getUser());

		List<DealInstrumentMap> oldDimList = oldDeal.getDealInstrumentMaps();
		List<DealInstrumentMap> newDimList = new ArrayList<DealInstrumentMap>();
		InstrumentTransaction insTraOne = null;
		InstrumentTransaction insTraTwo = null;
		InstrumentTransaction insTraThree = null;
		InstrumentTransaction insTraFour = null;

		if (oldDeal.getDealType().getCode().equals("PURCH")) {
			if (oldDimList == null) {
				shortMaturityDto.setStatus("Error, No DIM List found for Purchase");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			}
			DealInstrumentMap dim = oldDimList.get(0);
			if (dim == null) {
				shortMaturityDto.setStatus("Error, No DIM record found for Purchase");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			}
			if (dim.getInstrument() == null) {
				shortMaturityDto.setStatus("Error, No Instruments found for the Purchase");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			}
			dim.getInstrument().setMaturityDate(newMatDate);

			DealInstrumentMap newDim = new DealInstrumentMap();
			newDim.setDate(new Date());
			newDim.setDeal(newDeal);
			newDim.setInstrument(dim.getInstrument());
			newDim.setInstrumentTransactions(new ArrayList<InstrumentTransaction>());
			newDimList.add(newDim);

		} else if (oldDeal.getDealType().getCode().equals("REPO")) {
			if (oldDimList == null) {
				shortMaturityDto.setStatus("Error, No DIM List found for Repo");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			}
			if (oldDimList.size() < 1) {
				shortMaturityDto.setStatus("Repo needs atleast one collateral");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			} else {
				Iterator<DealInstrumentMap> iter = oldDimList.iterator();
				while (iter.hasNext()) {
					DealInstrumentMap oldDim = iter.next();

					// for(DealInstrumentMap oldDim : oldDimList){
					DealInstrumentMap newDim = new DealInstrumentMap();
					newDim.setDate(new Date());
					newDim.setDeal(newDeal);
					newDim.setInstrument(oldDim.getInstrument());
					newDim.setInstrumentTransactions(new ArrayList<InstrumentTransaction>());

					if (oldDim.getInstrument() == null) {
						shortMaturityDto.setStatus("Cannot Find Instrument: " + oldDim.getDeal().getDealCode());
						shortMaturityDto.setSuccess(false);
						return newDeal;
					} else {
						oldDim.getInstrument().setMaturityDate(newMatDate);
						oldDim.getInstrument().setLastDeal(newDeal);
					}
					Collections.sort(oldDim.getInstrumentTransactions(), new Comparator<InstrumentTransaction>() {
						@Override
						public int compare(InstrumentTransaction insTraOne, InstrumentTransaction insTraTwo) {
							return insTraOne.getDate().compareTo(insTraTwo.getDate());
						}
					});

					for (InstrumentTransaction oldInsTra : oldDim.getInstrumentTransactions()) {
						InstrumentTransaction newInsTra = new InstrumentTransaction();
						newInsTra.setComment(oldInsTra.getComment());
						newInsTra.setDate(new Date());
						newInsTra.setDealInstrumentMap(newDim);
						newInsTra.setModifiedDate(new Date());
						newInsTra.setStatus(oldInsTra.getStatus());
						newInsTra.setTransAmount(oldInsTra.getTransAmount());
						newDim.setStatus(oldInsTra.getComment());
						newDim.addInstrumentTransaction(newInsTra);
					}

					if (oldDim.getInstrumentTransactions().size() == 1) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = null;
						insTraThree = null;
						insTraFour = null;
					} else if (oldDim.getInstrumentTransactions().size() == 2) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = oldDim.getInstrumentTransactions().get(1);
						insTraThree = null;
						insTraFour = null;
					} else if (oldDim.getInstrumentTransactions().size() == 3) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = oldDim.getInstrumentTransactions().get(1);
						insTraThree = oldDim.getInstrumentTransactions().get(2);
						insTraFour = null;
					} else if (oldDim.getInstrumentTransactions().size() == 2) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = oldDim.getInstrumentTransactions().get(1);
						insTraThree = oldDim.getInstrumentTransactions().get(2);
						insTraFour = oldDim.getInstrumentTransactions().get(3);
					} else {
						insTraOne = null;
						insTraTwo = null;
					}

					if (insTraOne == null) {
						insTraOne = new InstrumentTransaction();
						insTraOne.setDealInstrumentMap(oldDim);
						insTraOne.setDate(new Date());
						insTraOne.setComment("Issued by Custodian");
						insTraOne.setStatus("IN");
						oldDim.getInstrumentTransactions().add(insTraOne);
					}
					insTraOne.setTransAmount(new BigDecimal(0));
					if (insTraTwo == null) {
						insTraTwo = new InstrumentTransaction();
						insTraTwo.setDealInstrumentMap(oldDim);
						insTraTwo.setStatus("OUT");
						oldDim.getInstrumentTransactions().add(insTraTwo);
						insTraTwo.setDate(new Date());
						insTraTwo.setComment("Dispatched to Customer");
					}
					insTraTwo.setTransAmount(new BigDecimal(0));
					if (insTraThree == null) {
						insTraThree = new InstrumentTransaction();
						insTraThree.setDealInstrumentMap(oldDim);
						insTraThree.setStatus("IN");
						oldDim.getInstrumentTransactions().add(insTraThree);
						insTraThree.setDate(new Date());
						insTraThree.setComment("Exchanged-IN From Customer");
					}
					insTraThree.setTransAmount(new BigDecimal(0));
					if (insTraFour == null) {
						insTraFour = new InstrumentTransaction();
						insTraFour.setDealInstrumentMap(oldDim);
						insTraFour.setStatus("OUT");
						oldDim.getInstrumentTransactions().add(insTraFour);
						insTraFour.setDate(new Date());
						insTraFour.setComment("Exchanged-IN To Custodian");
					}
					insTraFour.setTransAmount(new BigDecimal(0));
					oldDim.setStatus("Exchanged-IN To Custodian");

					// oldDimList.add(oldDim);
					newDimList.add(newDim);
					insTraOne = null;
					insTraTwo = null;
					insTraThree = null;
					insTraFour = null;
				}
				// dealDao.updateDims(dimList, insIssueReceiveDto);
			}
		} else if (oldDeal.getDealType().getCode().equals("RREPO")) {
			if (oldDimList == null) {
				shortMaturityDto.setStatus("Error, No DIM List found for RRepo");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			}
			if (oldDimList.size() < 1) {
				shortMaturityDto.setStatus("RRepo needs atleast one collateral");
				shortMaturityDto.setSuccess(false);
				return newDeal;
			} else {
				for (DealInstrumentMap oldDim : oldDimList) {
					DealInstrumentMap newDim = new DealInstrumentMap();
					newDim.setDate(new Date());
					newDim.setDeal(newDeal);
					newDim.setInstrument(oldDim.getInstrument());
					newDim.setInstrumentTransactions(new ArrayList<InstrumentTransaction>());

					if (oldDim.getInstrument() == null) {
						shortMaturityDto.setStatus("Cannot Find Instrument: " + oldDim.getDeal().getDealCode());
						shortMaturityDto.setSuccess(false);
						return newDeal;
					} else {
						oldDim.getInstrument().setMaturityDate(newMatDate);
						oldDim.getInstrument().setLastDeal(newDeal);
					}

					Collections.sort(oldDim.getInstrumentTransactions(), new Comparator<InstrumentTransaction>() {
						@Override
						public int compare(InstrumentTransaction insTraOne, InstrumentTransaction insTraTwo) {
							return insTraOne.getDate().compareTo(insTraTwo.getDate());
						}
					});

					for (InstrumentTransaction oldInsTra : oldDim.getInstrumentTransactions()) {
						InstrumentTransaction newInsTra = new InstrumentTransaction();
						newInsTra.setComment(oldInsTra.getComment());
						newInsTra.setDate(new Date());
						newInsTra.setDealInstrumentMap(newDim);
						newInsTra.setModifiedDate(new Date());
						newInsTra.setStatus(oldInsTra.getStatus());
						newInsTra.setTransAmount(oldInsTra.getTransAmount());
						newDim.setStatus(oldInsTra.getComment());
						newDim.addInstrumentTransaction(newInsTra);
					}

					if (oldDim.getInstrumentTransactions().size() == 1) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = null;
						insTraThree = null;
						insTraFour = null;
					} else if (oldDim.getInstrumentTransactions().size() == 2) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = oldDim.getInstrumentTransactions().get(1);
						insTraThree = null;
						insTraFour = null;
					} else if (oldDim.getInstrumentTransactions().size() == 3) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = oldDim.getInstrumentTransactions().get(1);
						insTraThree = oldDim.getInstrumentTransactions().get(2);
						insTraFour = null;
					} else if (oldDim.getInstrumentTransactions().size() == 2) {
						insTraOne = oldDim.getInstrumentTransactions().get(0);
						insTraTwo = oldDim.getInstrumentTransactions().get(1);
						insTraThree = oldDim.getInstrumentTransactions().get(2);
						insTraFour = oldDim.getInstrumentTransactions().get(3);
					} else {
						insTraOne = null;
						insTraTwo = null;
					}

					if (insTraOne == null) {
						insTraOne = new InstrumentTransaction();
						insTraOne.setDealInstrumentMap(oldDim);
						insTraOne.setDate(new Date());
						insTraOne.setComment("Received From Customer");
						insTraOne.setStatus("IN");
						oldDim.getInstrumentTransactions().add(insTraOne);
					}
					insTraOne.setTransAmount(new BigDecimal(0));
					if (insTraTwo == null) {
						insTraTwo = new InstrumentTransaction();
						insTraTwo.setDealInstrumentMap(oldDim);
						insTraTwo.setStatus("OUT");
						oldDim.getInstrumentTransactions().add(insTraTwo);
						insTraTwo.setDate(new Date());
						insTraTwo.setComment("Dispatched to Custodian");
					}
					insTraTwo.setTransAmount(new BigDecimal(0));
					if (insTraThree == null) {
						insTraThree = new InstrumentTransaction();
						insTraThree.setDealInstrumentMap(oldDim);
						insTraThree.setStatus("IN");
						oldDim.getInstrumentTransactions().add(insTraThree);
						insTraThree.setDate(new Date());
						insTraThree.setComment("Issued by Custodian");
					}
					insTraThree.setTransAmount(new BigDecimal(0));
					if (insTraFour == null) {
						insTraFour = new InstrumentTransaction();
						insTraFour.setDealInstrumentMap(oldDim);
						insTraFour.setStatus("OUT");
						oldDim.getInstrumentTransactions().add(insTraFour);
						insTraFour.setDate(new Date());
						insTraFour.setComment("Dispatched to Customer");
					}
					insTraFour.setTransAmount(new BigDecimal(0));
					oldDim.setStatus("Exchanged-Out To Customer");

					// oldDimList.add(oldDim);
					newDimList.add(newDim);
					insTraOne = null;
					insTraTwo = null;
					insTraThree = null;
					insTraFour = null;
				}
				// dealDao.updateDims(dimList, insIssueReceiveDto);
				// newDeal.setDealInstrumentMaps(newDimList);
			}
		}
		newDeal.setDealInstrumentMaps(newDimList);
		dealDao.updateSM(oldDeal, newDeal, shortMaturityDto);
		System.out.println("OldDeal:" + oldDeal.getDealCode());
		System.out.println("NewMatDate:" + newMatDate);
		System.out.println("newRAte:" + shortMaturityDto.getNewActualRate());

		return newDeal;
	}

}
